/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package comp353Games;

import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.*;
import javax.swing.*;

/**
 * GeneralController is the vehicle by which all the games iterate.
 *
 * @author Tyler Radley, Andre Harvey, Deanna Fink
 * @version February 27, 2012
 */
public class GeneralController2 extends JFrame implements MouseListener {
    //An instance of the current game.

    private GeneralGame[] game;
    private GeneralGame[] newGame;
    private Snort snort;
    //Number of valid moves made in the game
    private boolean firstPly = true;
    //Initializes the coordinates of each mouse interaction.
    private int[] gamePress = new int[2];
    private int[] gameRelease = new int[2];
    private int[] gameClick = new int[]{-1, -1};
    // The JFrame we are displaying the game in.
    private JFrame frame;
    private JPanel gamePanel0 = new JPanel();
    private JPanel gamePanel1 = new JPanel();
    //The JLabels we are displaying the status of the games in.
    private JLabel statusBar0;
    private JLabel statusBar1;
    private static int currentPlayer;
    public static final int NUM_PLAYERS = 2;

    /**
     * Constructor for the general controller that sets the initial attributes
     * of the JFrame and starts the game.
     */
    public void GeneralController2() {
        this.frame = new JFrame(game[0].getName() +" & "+ game[1].getName());
        this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.frame.setPreferredSize(new Dimension(1000 + (280 * (game.length - 1)), 600));
        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        JMenu file = new JMenu("File");
        menuBar.add(file);
        JMenuItem New = new JMenuItem("New");
        JMenuItem ChooGame = new JMenuItem("Game Chooser");

        New = new JMenuItem("New Game", KeyEvent.VK_T);
        New.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
        New.getAccessibleContext().setAccessibleDescription(
                "Starts a new Game");

        New.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent event) {
                newGameActionPerformed(event);
            }
        });

        ChooGame = new JMenuItem("Game Chooser", KeyEvent.VK_T);
        ChooGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
        ChooGame.getAccessibleContext().setAccessibleDescription(
                "Opens the Game Choice Menu");

        ChooGame.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent event) {
                chooGameActionPerformed(event);
            }
        });
        file.add(New);
        file.add(ChooGame);
        this.statusBar0 = new JLabel(game[0].getInstructions(currentPlayer)[0] + game[0].getInstructions(currentPlayer)[1], SwingConstants.CENTER);
        this.statusBar1 = new JLabel(game[1].getInstructions(currentPlayer)[0] + game[1].getInstructions(currentPlayer)[1], SwingConstants.CENTER);
        this.gamePanel0.add(statusBar0, BorderLayout.SOUTH);
        this.gamePanel1.add(statusBar1, BorderLayout.SOUTH);
        this.frame.getContentPane().add(gamePanel0, BorderLayout.WEST);
        this.frame.getContentPane().add(gamePanel1, BorderLayout.EAST);
        this.gamePanel0.addMouseListener(this);
        this.gamePanel1.addMouseListener(this);
        this.frame.addMouseListener(this);
        this.displayGame();

        //Display the window.
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
    }

    /**
     * Class constructor for generic game.
     *
     * @param game game to begin with.
     */
    public GeneralController2(GeneralGame[] game) {
        this.game = game;
        this.currentPlayer = 1;
    }

    /**
     * Creates a display for the game.
     */
    public void displayGame() {
        this.gamePanel0.add(game[0].getDisplay(this.game[0]));
        this.gamePanel0.add(statusBar0, BorderLayout.SOUTH);
        this.gamePanel1.add(game[1].getDisplay(this.game[1]));
        this.gamePanel1.add(statusBar1, BorderLayout.SOUTH);
        this.frame.add(gamePanel0, BorderLayout.WEST);
        this.frame.add(gamePanel1, BorderLayout.EAST);
        this.frame.setVisible(true);
        this.frame.pack();
        this.frame.repaint();
    }

    @Override
    public void mousePressed(java.awt.event.MouseEvent event) {
        this.gamePress = game[0].mousePress(event.getX(), event.getY());
        if (gamePress == null) {
            this.gamePress = game[1].mousePress(event.getX(), event.getY());
        }
    }

    @Override
    public void mouseReleased(java.awt.event.MouseEvent event) {
        this.gameRelease = game[0].mouseRelease(event.getX(), event.getY());
        if (gameRelease != null) {
            move(0);
        } else {
            this.gameRelease = game[1].mouseRelease(event.getX(), event.getY());
            if (gameRelease != null) {
                move(1);
            }
        }
    }

    @Override
    public void mouseClicked(java.awt.event.MouseEvent event) {
        this.gameClick = new int[]{-1, -1};
        this.gameClick = game[0].mouseClick(event.getX(), event.getY(), currentPlayer);
        if (gameClick != null) {
            move(0);
        } else {
            this.gameClick = game[0].mouseClick(event.getX(), event.getY(), currentPlayer);
            if (gameClick != null) {
                move(1);
            }
        }
    }

    /**
     * If the move is valid, moves to a new game and checks to see if there are
     * any more moves.
     *
     * @param game New game to make a move to.
     */
    public void move(int currentGame) {
        if ((gamePress != null && gameRelease != null || gameClick != null) && game[currentGame].validMove(gamePress, gameRelease, gameClick, currentPlayer)) {
            this.game[currentGame] = game[currentGame].updateGame(gamePress, gameRelease, gameClick, currentPlayer);
            this.currentPlayer = currentPlayer % NUM_PLAYERS + 1;
            if (game[currentGame].hasMovesRemaining(currentPlayer)) {
                statusBar0.setText(game[0].getInstructions(currentPlayer)[1]);
                statusBar1.setText(game[1].getInstructions(currentPlayer)[1]);
                this.displayGame();
            } else {
                if (currentGame == 0) {
                } else {
                    if (game[currentGame % 1].hasMovesRemaining(currentPlayer)) {
                        statusBar0.setText("There are no more moves left in this game.");
                    } else {
                        this.displayGame();
                        statusBar0.setText("Sorry, " + game[0].getInstructions(currentPlayer)[2] + ", there are no more moves for you, you lose. Start a new game or return to the Game Chooser.");
                        statusBar1.setText("Sorry, " + game[1].getInstructions(currentPlayer)[2] + ", there are no more moves for you, you lose. Start a new game or return to the Game Chooser.");
                    }
                }
            }
        }
    }

    /**
     * Returns a string version of this.
     *
     * @param indent Indentation string.
     * @return //An empty string.
     */
    public String toString(String indent) {
        String string = "";
        return string;
    }

    @Override
    public String toString() {
        return this.toString("");
    }

    //Defines what happens when new game is selected from the file menu.
    private void newGameActionPerformed(java.awt.event.ActionEvent event) {
        Object[] options = {"Yes", "No, return to the game"};
        String resignNew = "";
        if (game[0].hasMovesRemaining(currentPlayer)||game[1].hasMovesRemaining(currentPlayer)) {
            resignNew = game[0].getInstructions(currentPlayer)[2]+"/" +game[1].getInstructions(currentPlayer)[2]+" are you sure you want to resign and start a new game?";
        } else {
            resignNew = "Are you sure you want to exit?";
        }
        int n = JOptionPane.showOptionDialog(frame, resignNew, "",
                JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE,
                null, options, options[1]);
        if (n == 0) {
            this.frame.dispose();
            new Thread(new Runnable() {

                public void run() {
                    newGame[0] = game[0].getNewGame();
                    newGame[1] = game[1].getNewGame();
                    GeneralController2 controller = new GeneralController2(newGame);
                    controller.GeneralController2();
                }
            }).start();
        }
    }

    //Defines what happens when the game chooser option is selected from the file menu
    private void chooGameActionPerformed(java.awt.event.ActionEvent event) {
        Object[] options = {"Yes", "No, return to the game"};
        String resignNew = "";
        if (game[0].hasMovesRemaining(currentPlayer)||game[1].hasMovesRemaining(currentPlayer)) {
            resignNew = game[0].getInstructions(currentPlayer)[2]+"/"+game[1].getInstructions(currentPlayer)[2]+" are you sure you want to resign this game and return to the game chooser?";
        } else {
            resignNew = "Are you sure you want to start a return to the game chooser?";
        }
        int n = JOptionPane.showOptionDialog(frame, resignNew,
                "", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE,
                null, options, options[1]);
        if (n == 0) {
            this.frame.dispose();
            new Thread(new Runnable() {

                public void run() {
                    Opener2.main(null);
                }
            }).start();
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}
}
